#pragma once

#include "njm_model.hpp"
#include <memory>
#include <unordered_map>
#include <glm/gtc/matrix_transform.hpp>

namespace njm {

    struct TransformComponent
    {
        glm::vec3 translation{};
        glm::vec3 scale{1.f, 1.f, 1.f};
        glm::vec3 rotation{};
        glm::mat4 mat4();
        glm::mat3 normalMatrix();
    };

    struct PointLightComponent {
        float lightIntensity{1.f};
    };
    
    class NjmGameObj
    {
    public:
        using id_t = unsigned int;
        using Map = std::unordered_map<id_t, NjmGameObj>;

        static NjmGameObj createGameObj();
        static NjmGameObj createPointLight(
            float lightIntensity = 0.5f,
            float radius = 0.1f,
            glm::vec3 color = glm::vec3(1.f)
        );

        ~NjmGameObj();
        NjmGameObj(const NjmGameObj&) = delete;
        NjmGameObj& operator=(const NjmGameObj&) = delete;
        NjmGameObj(NjmGameObj&&) = default;
        NjmGameObj& operator=(NjmGameObj&&) = default;

        id_t getId() const { return id; }

        glm::vec3 color{};
        TransformComponent transform{};
        // optional ptrs
        std::shared_ptr<NjmModel> model{};
        std::unique_ptr<PointLightComponent> pointLight = nullptr;

    private:
        NjmGameObj(id_t objId);
        id_t id;
    };

}